package com.mf.framework.component.mybatis.dialect;

import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;

import java.util.*;

/**
 * Mybatis方言抽象类
 * User: zhaoming
 * Date: 2017/6/15 10:06
 * To change this template use File | Settings | File Templates.
 */
public abstract class Dialect {

	public enum Type {
		MYSQL, ORACLE, SQLSERVER
    }

	static final String SQL_END_DELIMITER = ";";

	/**
	 * 设置分页
	 */
	public abstract void setSqlLimit(MetaObject metaObject, BoundSql boundSql, int offset, int limit);

	/**
	 * 设置排序
	 */
	public void setSqlSort(MetaObject metaObject, BoundSql boundSql, LinkedHashMap<String, String> orderItems) {
		if (orderItems != null && orderItems.size() > 0) {
			Configuration configuration = (Configuration) metaObject.getValue("delegate.configuration");
			//获取SQL
			String sql = trim(boundSql.getSql());
			//获取参数映射
			List<ParameterMapping> parameterMappings = new ArrayList<>();
			if(boundSql.getParameterMappings() != null && boundSql.getParameterMappings().size() > 0){
				parameterMappings = boundSql.getParameterMappings();
			}
			//获取参数对象
			Map<String, Object> parameterObject = (Map<String, Object>)boundSql.getParameterObject();

			StringBuilder sqlBuilder = new StringBuilder();
			sqlBuilder.append(sql);
			String orderBySql = "";
			Iterator<Map.Entry<String, String>> it = orderItems.entrySet().iterator();
			int i = 0;
			while (it.hasNext()) {
				Map.Entry<String, String> entry = it.next();
				//设置SQL语句
				orderBySql = orderBySql + ", ? ?";
				//设置参数映射
				parameterMappings.add(new ParameterMapping.Builder(configuration, "_orderByKey"+i, String.class).build());
				parameterMappings.add(new ParameterMapping.Builder(configuration, "_orderByValue"+i, String.class).build());
				//设置参数值
				parameterObject.put("_orderByKey"+i, entry.getKey());
				parameterObject.put("_orderByValue"+i, entry.getValue());
				i++;
			}
			if (orderBySql.trim().length() > 0) {
				if (orderBySql.startsWith(",")) {
					sqlBuilder.append(" ORDER BY").append(orderBySql.substring(1));
				}
			}
			metaObject.setValue("delegate.boundSql.sql", sqlBuilder.toString());
			metaObject.setValue("delegate.boundSql.parameterMappings", parameterMappings);
			metaObject.setValue("delegate.boundSql.parameterObject", parameterObject);
		}
	}

	String trim(String sql) {
		sql = sql.trim();
		if (sql.endsWith(SQL_END_DELIMITER)) {
			sql = sql.substring(0, sql.length() - 1 - SQL_END_DELIMITER.length());
		}
		return sql;
	}
}
